package middleware

import (
	"admin-system/internal/config"
	"admin-system/internal/model"
	"admin-system/pkg/response"
	"strings"

	"github.com/gin-gonic/gin"
)

// Permission 权限检查中间件
func Permission(permissionCode string) gin.HandlerFunc {
	return func(c *gin.Context) {
		// 从上下文中获取用户ID
		userIDInterface, exists := c.Get("userID")
		if !exists {
			response.Unauthorized(c, "未授权")
			c.Abort()
			return
		}

		userID, ok := userIDInterface.(uint)
		if !ok {
			response.Unauthorized(c, "用户ID格式错误")
			c.Abort()
			return
		}

		// 检查用户是否有权限
		hasPermission, err := checkUserPermission(userID, permissionCode)
		if err != nil {
			response.ServerError(c, "权限检查失败: "+err.Error())
			c.Abort()
			return
		}

		if !hasPermission {
			response.Forbidden(c, "没有权限执行此操作")
			c.Abort()
			return
		}

		c.Next()
	}
}

// checkUserPermission 检查用户是否有指定权限
func checkUserPermission(userID uint, permissionCode string) (bool, error) {
	// 首先尝试检查具体的功能权限
	var count int64
	err := config.DB.Table("users").
		Joins("JOIN user_roles ON users.id = user_roles.user_id").
		Joins("JOIN roles ON user_roles.role_id = roles.id").
		Joins("JOIN role_permissions ON roles.id = role_permissions.role_id").
		Joins("JOIN permissions ON role_permissions.permission_id = permissions.id").
		Where("users.id = ? AND permissions.code = ? AND users.status = 1 AND roles.status = 1 AND permissions.status = 1",
			userID, permissionCode).
		Count(&count).Error

	if err != nil {
		return false, err
	}

	// 如果有具体的功能权限，直接返回
	if count > 0 {
		return true, nil
	}

	// 如果没有具体的功能权限，检查是否有对应的菜单权限
	// 根据权限代码推断菜单名称
	menuName := getMenuNameFromPermissionCode(permissionCode)
	if menuName == "" {
		return false, nil
	}

	// 检查用户是否有对应的菜单权限
	err = config.DB.Table("users").
		Joins("JOIN user_roles ON users.id = user_roles.user_id").
		Joins("JOIN roles ON user_roles.role_id = roles.id").
		Joins("JOIN role_menus ON roles.id = role_menus.role_id").
		Joins("JOIN menus ON role_menus.menu_id = menus.id").
		Where("users.id = ? AND menus.name = ? AND users.status = 1 AND roles.status = 1 AND menus.status = 1",
			userID, menuName).
		Count(&count).Error

	if err != nil {
		return false, err
	}

	return count > 0, nil
}

// getMenuNameFromPermissionCode 根据权限代码推断菜单名称
func getMenuNameFromPermissionCode(permissionCode string) string {
	// 权限代码格式：模块:操作，如 user:list, role:create
	parts := strings.Split(permissionCode, ":")
	if len(parts) != 2 {
		return ""
	}

	module := parts[0]

	// 将模块名转换为菜单名（首字母大写）
	switch module {
	case "user":
		return "User"
	case "role":
		return "Role"
	case "menu":
		return "Menu"
	case "permission":
		return "Permission"
	default:
		return ""
	}
}

// GetUserRoles 获取用户角色
func GetUserRoles(userID uint) ([]model.Role, error) {
	var roles []model.Role

	err := config.DB.Table("roles").
		Select("roles.*").
		Joins("JOIN user_roles ON roles.id = user_roles.role_id").
		Where("user_roles.user_id = ? AND roles.status = 1", userID).
		Find(&roles).Error

	return roles, err
}

// GetUserPermissions 获取用户权限
func GetUserPermissions(userID uint) ([]model.Permission, error) {
	var permissions []model.Permission

	err := config.DB.Table("permissions").
		Select("DISTINCT permissions.*").
		Joins("JOIN role_permissions ON permissions.id = role_permissions.permission_id").
		Joins("JOIN roles ON role_permissions.role_id = roles.id").
		Joins("JOIN user_roles ON roles.id = user_roles.role_id").
		Where("user_roles.user_id = ? AND permissions.status = 1 AND roles.status = 1", userID).
		Find(&permissions).Error

	return permissions, err
}

// GetUserMenus 获取用户菜单
func GetUserMenus(userID uint) ([]model.Menu, error) {
	var menus []model.Menu

	err := config.DB.Table("menus").
		Select("DISTINCT menus.*").
		Joins("JOIN role_menus ON menus.id = role_menus.menu_id").
		Joins("JOIN roles ON role_menus.role_id = roles.id").
		Joins("JOIN user_roles ON roles.id = user_roles.role_id").
		Where("user_roles.user_id = ? AND menus.status = 1 AND roles.status = 1", userID).
		Order("menus.sort ASC, menus.id ASC").
		Find(&menus).Error

	return menus, err
}
